﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FA.Library.Plugin;
using System.ComponentModel;
using FA.Library.Sim.Aircraft;

namespace FA.FlightAttendant.Plugin
{
    /// <summary>
    /// A wrapper class for IPlugin such that it can be decorated with some additional properties.
    /// </summary>
    public class Simulator : INotifyPropertyChanged, IDisposable
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public event EventHandler Disposed;

        public IPlugin Plugin { get; private set; }
        public bool IsDisposed { get; private set; }

        /// <summary>
        /// Name of the simulator.
        /// </summary>
        public string Name
        {
            get { return Plugin.Name; }
        }
        
        /// <summary>
        /// Settings for the simulator.
        /// </summary>
        public Dictionary<string, string> Settings
        {
            get { return Plugin.GetSettings(); }
        }

        /// <summary>
        /// Flag indicating if the simulator is running.
        /// </summary>
        public bool IsRunning
        {
            get { return Plugin.IsRunning; }
        }
        
        /// <summary>
        /// Simulator constructor.
        /// </summary>
        /// <param name="plugin"></param>
        public Simulator(IPlugin plugin)
        {
            Plugin = plugin;

            plugin.Disposed += new EventHandler(plugin_Disposing);
            plugin.OnPluginStartEvent += new EventHandler(plugin_OnPluginStartEvent);
            plugin.OnPluginStopEvent += new EventHandler(plugin_OnPluginStopEvent);
            plugin.OnPluginSettingsChangedEvent += new EventHandler(plugin_OnSettingsChangedEvent);
        }

        /// <summary>
        /// Dispose the simulator
        /// </summary>
        public void Dispose()
        {
            if (IsDisposed)
                return;
            
            if (Plugin != null && !Plugin.IsDisposed)
                Plugin.Dispose();

            IsDisposed = true;

            if (Disposed != null)
                Disposed(this, null);
        }
        
        /// Initialise the simulator.
        /// </summary>
        public void Initialise()
        {
            Plugin.Initialise();
        }

        /// <summary>
        /// Start the simulator.
        /// </summary>
        public void Start()
        {
            Plugin.Start();
        }

        /// <summary>
        /// Stop the simulator.
        /// </summary>
        public void Stop()
        {
            Plugin.Stop();
        }

        /// <summary>
        /// Update the aircraft model on this simulator.
        /// </summary>
        /// <param name="model"></param>
        public void UpdateAircraftModel(AircraftModel model, bool supressEvent)
        {
            Plugin.UpdateAircraftModel(model, supressEvent);
        }

        private void NotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }

        #region Event handlers

        private void plugin_OnPluginStartEvent(object sender, EventArgs e)
        {
            NotifyPropertyChanged("IsRunning");
        }

        private void plugin_OnPluginStopEvent(object sender, EventArgs e)
        {
            NotifyPropertyChanged("IsRunning");
        }

        private void plugin_OnSettingsChangedEvent(object sender, EventArgs e)
        {
            NotifyPropertyChanged("Settings");
        }

        private void plugin_Disposing(object sender, EventArgs e)
        {
            // Dispose the simulator when the plugin is disposed.
            Dispose();
        }

        #endregion
    }
}